package com.ruoyi.common.utils.opcua;

import com.google.common.collect.ImmutableList;
import lombok.Getter;
import org.eclipse.milo.opcua.sdk.core.Reference;
import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
import org.eclipse.milo.opcua.sdk.server.api.AddressSpaceManager;
import org.eclipse.milo.opcua.sdk.server.api.NodeManager;
import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig;
import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfigBuilder;
import org.eclipse.milo.opcua.sdk.server.identity.AnonymousIdentityValidator;
import org.eclipse.milo.opcua.sdk.server.nodes.*;
import org.eclipse.milo.opcua.stack.core.BuiltinReferenceType;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.NamespaceTable;
import org.eclipse.milo.opcua.stack.core.ReferenceType;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.transport.TransportProfile;
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode;
import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass;
import org.eclipse.milo.opcua.stack.core.types.structured.*;
import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder;
import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;
import org.eclipse.milo.opcua.stack.core.security.CertificateManager;
import org.eclipse.milo.opcua.stack.core.security.TrustListManager;
import org.eclipse.milo.opcua.stack.core.security.DefaultTrustListManager;
import org.eclipse.milo.opcua.stack.server.EndpointConfiguration;
import org.eclipse.milo.opcua.stack.core.channel.EncodingLimits;
import org.eclipse.milo.opcua.stack.server.security.ServerCertificateValidator;
import org.eclipse.milo.opcua.stack.server.security.DefaultServerCertificateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.time.Period;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * OPC UA服务器工具类，提供数据上传和获取方法
 * 适配Milo SDK 0.6.13和Java 8
 */
public class OpcUaServer1Util {
    private static final Logger log = LoggerFactory.getLogger(OpcUaServer1Util.class);
    private static volatile OpcUaServer1Util instance; // 单例实例

    // 常量定义
    private static final String NAMESPACE_URI = "urn:example:custom";
    private static final int UPDATE_INTERVAL_SECONDS = 5;
    private static final String APPLICATION_URI = "urn:eclipse:milo:optimized-server";
    private static final String OPC_UA_DEFAULT_NAMESPACE = "http://opcfoundation.org/UA/";
    private static final int SERVER_SHUTDOWN_TIMEOUT_SECONDS = 5;
    private static final int EXECUTOR_TERMINATION_TIMEOUT_SECONDS = 2;
    private static final int RSA_KEY_SIZE = 2048;
    private static final int CERTIFICATE_VALIDITY_YEARS = 1;

    // 默认父节点ID
    private static final NodeId DEFAULT_PARENT_NODE_ID = Identifiers.ObjectsFolder;

    // OPC UA内置节点ID常量
    private static final NodeId OBJECTS_FOLDER_ID = Identifiers.ObjectsFolder;
    private static final NodeId SERVER_NODE_ID = Identifiers.Server; // Server节点ID：ns=0, id=2253

    // 类型定义节点ID
    private static final NodeId FOLDER_TYPE_ID = Identifiers.FolderType;
    private static final NodeId BASE_DATA_VARIABLE_TYPE_ID = Identifiers.BaseDataVariableType;

    @Getter
    private final OpcUaServer server;
    private final AddressSpaceManager addressSpaceManager;
    private final ScheduledExecutorService executor;
    private final AtomicReference<UaVariableNode> demoNodeRef = new AtomicReference<>();
    private UShort namespaceIndex;
    private final Random random = new Random();
    private final String bindAddress;
    private final int serverPort;
    private final AtomicBoolean isRunning = new AtomicBoolean(false);

    // 节点管理器和上下文
    private NodeManager<UaNode> customNamespaceNodeManager;
    private final UaNodeContextImpl nodeContext;

    /**
     * 私有构造函数，防止外部实例化
     */
    private OpcUaServer1Util(String bindAddress, int serverPort) {
        this.bindAddress = bindAddress;
        this.serverPort = serverPort;

        try {
            log.info("开始初始化OPC UA服务器，绑定地址: {}，端口: {}", bindAddress, serverPort);
            OpcUaServerConfig config = createServerConfig();
            server = new OpcUaServer(config);

            // 初始化节点上下文
            this.nodeContext = new UaNodeContextImpl();

            // 获取地址空间管理器
            this.addressSpaceManager = server.getAddressSpaceManager();

            executor = Executors.newSingleThreadScheduledExecutor(runnable -> {
                Thread thread = new Thread(runnable, "opcua-value-updater");
                thread.setDaemon(true);
                return thread;
            });

            log.info("OPC UA服务器初始化完成");
        } catch (Exception e) {
            log.error("OPC UA服务器初始化失败", e);
            throw new RuntimeException("OPC UA服务器初始化失败", e);
        }
    }

    /**
     * 节点上下文实现类
     */
    private class UaNodeContextImpl implements UaNodeContext {
        @Override
        public OpcUaServer getServer() {
            return server;
        }

        @Override
        public NodeManager<UaNode> getNodeManager() {
            return customNamespaceNodeManager;
        }

        public Optional<UaNode> getNode(NodeId nodeId) {
            try {
                // 1. 先从自定义节点管理器查找
                if (customNamespaceNodeManager != null && customNamespaceNodeManager.containsNode(nodeId)) {
                    return customNamespaceNodeManager.getNode(nodeId);
                }
                // 2. 再从服务器地址空间查找内置节点
                return server.getAddressSpaceManager().getManagedNode(nodeId);
            } catch (Exception e) {
                log.error("获取节点失败: {}", nodeId, e);
                return Optional.empty();
            }
        }

        public Optional<UaNode> getNode(ExpandedNodeId expandedNodeId) {
            try {
                return expandedNodeId.toNodeId(server.getNamespaceTable())
                        .flatMap(this::getNode);
            } catch (Exception e) {
                log.error("获取扩展节点失败: {}", expandedNodeId, e);
                return Optional.empty();
            }
        }
    }

    /**
     * 静态工厂方法，获取单例实例并启动服务器
     */
    public static OpcUaServer1Util startServer(String bindAddress, int serverPort) {
        log.info("请求启动OPC UA服务器，绑定地址: {}，端口: {}", bindAddress, serverPort);

        if (instance == null || !instance.isRunning()) {
            synchronized (OpcUaServer1Util.class) {
                if (instance == null || !instance.isRunning()) {
                    instance = new OpcUaServer1Util(bindAddress, serverPort);
                    instance.internalStart();
                }
            }
        } else {
            log.info("OPC UA服务器已在运行中，无需重复启动");
        }
        return instance;
    }

    /**
     * 内部启动方法，封装启动逻辑
     */
    private void internalStart() {
        if (isRunning.get()) {
            log.info("OPC UA服务器已在运行中");
            return;
        }

        log.info("启动OPC UA服务器...");
        log.info("使用Milo SDK版本: {}", OpcUaServer.SDK_VERSION);

        try {
            CompletableFuture<OpcUaServer> startupFuture = server.startup();
            log.debug("等待服务器启动完成...");
            OpcUaServer startedServer = startupFuture.get(5, TimeUnit.SECONDS);

            // 注册自定义命名空间和节点管理器
            registerCustomNamespaceAndNodeManager();

            // 验证类型定义节点是否存在
            if (!validateTypeDefinitionNodes()) {
                log.error("类型定义节点验证失败，启动中止");
                stop();
                return;
            }

            // 验证命名空间注册
            if (!validateNamespaceRegistration()) {
                log.error("命名空间注册验证失败，启动中止");
                stop();
                return;
            }

            // 添加示例节点
            if (!addSampleNodes()) {
                log.error("添加示例节点失败，启动中止");
                stop();
                return;
            }

            isRunning.set(true);
            log.info("OPC UA服务器启动成功!");
            log.info("应用URI: {}", startedServer.getConfig().getApplicationUri());
            log.info("可用端点:");

            ImmutableList<EndpointDescription> endpoints = startedServer.getEndpointDescriptions();
            endpoints.forEach(endpoint -> {
                log.info(" - {}", endpoint.getEndpointUrl());
            });

            // 启动值更新器
            startValueUpdater();
        } catch (TimeoutException e) {
            log.error("服务器启动超时(5秒)", e);
            stop();
        } catch (Exception e) {
            log.error("服务器启动失败", e);
            stop();
        }
    }

    /**
     * 创建示例文件夹节点
     */
    private UaFolderNode createDemoFolderNode() {
        try {
            if (namespaceIndex == null) {
                log.error("命名空间索引为空，无法创建示例文件夹节点");
                return null;
            }

            NodeId folderNodeId = new NodeId(namespaceIndex, "DemoFolder");
            log.debug("创建示例文件夹节点，ID: {}", folderNodeId);

            // 验证类型定义节点是否存在
            Optional<UaNode> typeNode = nodeContext.getNode(FOLDER_TYPE_ID);
            if (!typeNode.isPresent()) {
                log.error("FolderType节点不存在，无法创建文件夹节点");
                return null;
            }

            // 创建文件夹节点
            UaFolderNode folderNode = new UaFolderNode(
                    nodeContext,
                    folderNodeId,
                    new QualifiedName(namespaceIndex, "Demo"),
                    LocalizedText.english("Demo")
            );

            // 设置类型定义引用
            folderNode.addReference(new Reference(
                    folderNode.getNodeId(),
                    BuiltinReferenceType.HasTypeDefinition.getNodeId(),
                    FOLDER_TYPE_ID.expanded(),
                    false
            ));

            folderNode.setNodeClass(NodeClass.Object);

            log.debug("示例文件夹节点创建成功: {}", folderNodeId);
            return folderNode;
        } catch (Exception e) {
            log.error("创建示例文件夹节点失败", e);
            return null;
        }
    }

    /**
     * 创建示例变量节点
     */
    private UaVariableNode createDemoVariableNode() {
        try {
            if (namespaceIndex == null) {
                log.error("命名空间索引为空，无法创建示例变量节点");
                return null;
            }

            NodeId nodeId = new NodeId(namespaceIndex, "DemoVariable");
            log.debug("创建示例变量节点，ID: {}", nodeId);

            // 验证类型定义节点
            Optional<UaNode> typeNode = nodeContext.getNode(BASE_DATA_VARIABLE_TYPE_ID);
            if (!typeNode.isPresent()) {
                log.error("BaseDataVariableType节点不存在，无法创建示例变量节点");
                return null;
            }

            // 构建示例变量节点
            UaVariableNode demoNode = new UaVariableNode.UaVariableNodeBuilder(nodeContext)
                    .setNodeId(nodeId)
                    .setBrowseName(new QualifiedName(namespaceIndex, "DemoVariable"))
                    .setDisplayName(LocalizedText.english("Demo Variable"))
                    .setDescription(LocalizedText.english("Demo variable for testing"))
                    .setDataType(Identifiers.Double)
                    .setAccessLevel(UByte.valueOf(3)) // 可读可写
                    .setUserAccessLevel(UByte.valueOf(3))
                    .setMinimumSamplingInterval(500D)
                    .setHistorizing(false)
                    .setValue(new DataValue(
                            new Variant(0.0), // 初始值
                            StatusCode.GOOD,
                            DateTime.now()
                    ))
                    .build();

            // 添加类型定义引用
            demoNode.addReference(new Reference(
                    nodeId,
                    BuiltinReferenceType.HasTypeDefinition.getNodeId(),
                    BASE_DATA_VARIABLE_TYPE_ID.expanded(),
                    false
            ));

            // 补充元数据
            demoNode.setWriteMask(UInteger.MAX);
            demoNode.setUserWriteMask(UInteger.MAX);

            log.debug("示例变量节点创建成功: {}", nodeId);
            return demoNode;
        } catch (Exception e) {
            log.error("创建示例变量节点失败", e);
            return null;
        }
    }

    /**
     * 添加示例节点
     */
    private boolean addSampleNodes() {
        try {
            // 验证必要条件
            if (namespaceIndex == null || customNamespaceNodeManager == null) {
                log.error("命名空间索引或节点管理器未初始化，无法添加节点");
                return false;
            }

            // 创建示例文件夹节点
            UaFolderNode demoFolderNode = createDemoFolderNode();
            if (demoFolderNode == null) {
                log.error("创建示例文件夹节点失败");
                return false;
            }

            // 添加文件夹节点
            boolean folderAdded = customNamespaceNodeManager.addNode(demoFolderNode).isPresent();
            if (!folderAdded) {
                log.warn("示例文件夹节点添加失败，可能已存在: {}", demoFolderNode.getNodeId());
            } else {
                log.info("示例文件夹节点添加成功: {}", demoFolderNode.getNodeId());
            }

            // 创建示例变量节点
            UaVariableNode demoNode = createDemoVariableNode();
            if (demoNode == null) {
                log.error("创建示例变量节点失败");
                return false;
            }

            // 添加变量节点
            boolean nodeAdded = customNamespaceNodeManager.addNode(demoNode).isPresent();
            if (!nodeAdded) {
                log.warn("示例变量节点添加失败，可能已存在: {}", demoNode.getNodeId());
            } else {
                log.info("示例变量节点添加成功: {}", demoNode.getNodeId());
            }

            // 建立节点间引用关系
            addNodeHierarchyReferences(demoFolderNode, demoNode);
            addNodeHierarchyReferences(getNode(OBJECTS_FOLDER_ID), demoFolderNode);

            // 保存节点引用
            demoNodeRef.set(demoNode);

            log.info("已添加示例节点和引用关系");
            return true;
        } catch (Exception e) {
            log.error("添加示例节点失败", e);
            return false;
        }
    }

    /**
     * 建立节点间的层次引用关系
     * 优化点：确保Objects和Server节点下使用Organizes引用
     */
    private void addNodeHierarchyReferences(UaNode parentNode, UaNode childNode) {
        try {
            if (parentNode == null || childNode == null) {
                log.error("父节点或子节点为空，无法建立引用关系");
                return;
            }

            NodeId parentId = parentNode.getNodeId();
            NodeId childId = childNode.getNodeId();
            log.debug("建立引用关系: 父节点={}, 子节点={}", parentId, childId);

            // 明确区分特殊节点下的引用处理
            boolean isObjectsNode = parentId.equals(OBJECTS_FOLDER_ID);
            boolean isServerNode = parentId.equals(SERVER_NODE_ID);

            ReferenceType referenceType;
            if (isObjectsNode || isServerNode) {
                // Objects和Server节点下强制使用Organizes引用
                referenceType = BuiltinReferenceType.Organizes;
                log.debug("父节点为{}，强制使用Organizes引用确保可见性",
                        isObjectsNode ? "Objects文件夹" : "Server节点");
            } else if (childNode.getNodeClass() == NodeClass.Object) {
                referenceType = BuiltinReferenceType.Organizes;
            } else {
                referenceType = BuiltinReferenceType.HasComponent;
            }

            // 添加正向和反向引用
            addBidirectionalReference(parentId, childId, referenceType);

            // 触发地址空间变更通知
            triggerAddressSpaceChange(childNode);

        } catch (Exception e) {
            log.error("添加父子节点引用失败", e);
        }
    }

    /**
     * 触发地址空间变更通知（适配Milo 0.6.13）
     */
    private void triggerAddressSpaceChange(UaNode node) {
        try {
            // 通过事件总线通知
            server.getEventBus().post(new NodeAddedEvent(node));

            // 对于变量节点，触发值变化事件
            if (node instanceof UaVariableNode) {
                server.getEventBus().post(new ValueChangedEvent((UaVariableNode) node));

            }

            log.debug("地址空间变更通知已触发，节点: {}", node.getNodeId());
        } catch (Exception e) {
            log.error("触发地址空间变更通知失败", e);
        }
    }

    /**
     * 添加双向引用（确保引用完整性）
     */
    private void addBidirectionalReference(NodeId parentId, NodeId childId, ReferenceType referenceType) {
        try {
            NodeId refTypeId = referenceType.getNodeId();

            // 正向引用：父节点 -> 子节点
            Reference forwardRef = new Reference(
                    parentId,
                    refTypeId,
                    childId.expanded(),
                    true // 正向引用
            );
            addReferenceToAllManagers(forwardRef);

            // 反向引用：子节点 -> 父节点
            Reference inverseRef = new Reference(
                    childId,
                    refTypeId,
                    parentId.expanded(),
                    false // 反向引用
            );
            addReferenceToAllManagers(inverseRef);

        } catch (Exception e) {
            log.error("添加双向引用失败", e);
        }
    }

    /**
     * 向所有相关节点管理器添加引用
     */
    private void addReferenceToAllManagers(Reference reference) {
        try {
            NodeId sourceNodeId = reference.getSourceNodeId();

            // 同时添加到自定义管理器和内置管理器
            if (customNamespaceNodeManager != null &&
                    customNamespaceNodeManager.containsNode(sourceNodeId)) {
                customNamespaceNodeManager.addReference(reference);
            }

            // 对于内置节点，添加到地址空间管理器的托管节点
            Optional<UaNode> node = server.getAddressSpaceManager().getManagedNode(sourceNodeId);
            if (node.isPresent()) {
                node.get().addReference(reference);
            }

            log.debug("引用已添加到相关管理器: {} -> {}",
                    sourceNodeId, reference.getTargetNodeId());
        } catch (Exception e) {
            log.error("向管理器添加引用失败", e);
        }
    }

    /**
     * 创建服务器配置
     */
    private OpcUaServerConfig createServerConfig() throws Exception {
        // 创建安全目录
        Path securityDir = Paths.get(System.getProperty("user.home"), ".milo", "security");
        Files.createDirectories(securityDir);
        log.debug("安全目录创建成功: {}", securityDir.toAbsolutePath());

        // 生成密钥对和证书
        log.debug("开始生成密钥对和证书...");
        KeyPair keyPair = generateKeyPair();
        X509Certificate certificate = generateCertificate(keyPair);
        log.debug("密钥对和证书生成完成");

        // 创建自定义证书管理器
        CertificateManager certificateManager = new DefaultCertificateManagerImpl(certificate, keyPair);

        // 创建信任列表管理器
        TrustListManager trustListManager = new DefaultTrustListManager(securityDir.toFile());

        // 创建证书验证器
        ServerCertificateValidator certificateValidator = new DefaultServerCertificateValidator(trustListManager);

        // 构建服务器信息
        BuildInfo buildInfo = new BuildInfo(
                APPLICATION_URI,
                "Eclipse Milo",
                "Optimized OPC UA Server",
                OpcUaServer.SDK_VERSION,
                "",
                DateTime.now()
        );

        // 使用内置的匿名令牌策略
        UserTokenPolicy anonymousPolicy = OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS;

        // 配置端点
        EndpointConfiguration.Builder endpointBuilder = new EndpointConfiguration.Builder();
        endpointBuilder.setTransportProfile(TransportProfile.TCP_UASC_UABINARY);
        endpointBuilder.setBindAddress(bindAddress);
        endpointBuilder.setBindPort(serverPort);
        endpointBuilder.setHostname(getHostname());
        endpointBuilder.setSecurityPolicy(SecurityPolicy.None);
        endpointBuilder.setSecurityMode(MessageSecurityMode.None);
        endpointBuilder.addTokenPolicies(anonymousPolicy);

        EndpointConfiguration endpointConfig = endpointBuilder.build();

        // 将端点配置添加到Set集合
        Set<EndpointConfiguration> endpoints = new HashSet<>();
        endpoints.add(endpointConfig);

        // 配置编码限制
        EncodingLimits encodingLimits = new EncodingLimits();

        // 创建执行器服务
        ExecutorService executorService = Executors.newFixedThreadPool(
                Runtime.getRuntime().availableProcessors() * 2,
                runnable -> {
                    Thread thread = new Thread(runnable, "opcua-executor-" + UUID.randomUUID().toString().substring(0, 8));
                    thread.setDaemon(true);
                    return thread;
                }
        );

        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(
                1,
                runnable -> {
                    Thread thread = new Thread(runnable, "opcua-scheduled-executor");
                    thread.setDaemon(true);
                    return thread;
                }
        );

        // 构建服务器配置
        OpcUaServerConfigBuilder configBuilder = OpcUaServerConfig.builder();

        configBuilder.setEndpoints(endpoints)
                .setApplicationName(LocalizedText.english("Optimized Milo OPC UA Server"))
                .setApplicationUri(APPLICATION_URI)
                .setProductUri(APPLICATION_URI)
                .setCertificateManager(certificateManager)
                .setTrustListManager(trustListManager)
                .setCertificateValidator(certificateValidator)
                .setExecutor(executorService)
                .setScheduledExecutorService(scheduledExecutorService)
                .setBuildInfo(buildInfo)
                .setEncodingLimits(encodingLimits)
                .setMinimumSecureChannelLifetime(UInteger.valueOf(60000))
                .setMaximumSecureChannelLifetime(UInteger.valueOf(3600000))
                .setIdentityValidator(new AnonymousIdentityValidator());

        log.debug("服务器配置创建完成");
        return configBuilder.build();
    }

    /**
     * 证书管理器实现类
     */
    private static class DefaultCertificateManagerImpl implements CertificateManager {
        private final X509Certificate certificate;
        private final KeyPair keyPair;
        private final Set<KeyPair> keyPairs = new HashSet<>();
        private final Set<X509Certificate> certificates = new HashSet<>();
        private final ByteString certificateByteString;

        public DefaultCertificateManagerImpl(X509Certificate certificate, KeyPair keyPair) throws CertificateEncodingException {
            this.certificate = certificate;
            this.keyPair = keyPair;

            this.keyPairs.add(keyPair);
            this.certificates.add(certificate);
            this.certificateByteString = ByteString.of(certificate.getEncoded());
        }

        @Override
        public Optional<KeyPair> getKeyPair(ByteString thumbprint) {
            if (thumbprint.equals(certificateByteString)) {
                return Optional.of(keyPair);
            }
            return Optional.empty();
        }

        @Override
        public Optional<X509Certificate> getCertificate(ByteString thumbprint) {
            if (thumbprint.equals(certificateByteString)) {
                return Optional.of(certificate);
            }
            return Optional.empty();
        }

        @Override
        public Optional<X509Certificate[]> getCertificateChain(ByteString thumbprint) {
            if (thumbprint.equals(certificateByteString)) {
                return Optional.of(new X509Certificate[]{certificate});
            }
            return Optional.empty();
        }

        @Override
        public Set<KeyPair> getKeyPairs() {
            return Collections.unmodifiableSet(keyPairs);
        }

        @Override
        public Set<X509Certificate> getCertificates() {
            return Collections.unmodifiableSet(certificates);
        }
    }

    private String getHostname() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            log.warn("无法获取主机名，使用默认值: localhost", e);
            return "localhost";
        }
    }

    private KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(RSA_KEY_SIZE);
        return keyPairGenerator.generateKeyPair();
    }

    private X509Certificate generateCertificate(KeyPair keyPair) throws Exception {
        String hostname = getHostname();
        String ipAddress = InetAddress.getLocalHost().getHostAddress();

        SelfSignedCertificateGenerator generator = new SelfSignedCertificateGenerator();

        return new SelfSignedCertificateBuilder(keyPair, generator)
                .setValidityPeriod(Period.ofYears(CERTIFICATE_VALIDITY_YEARS))
                .setCommonName(hostname)
                .setOrganization("Eclipse Milo")
                .setOrganizationalUnit("OPC UA Server")
                .setCountryCode("CN")
                .setApplicationUri(APPLICATION_URI)
                .addDnsName(hostname)
                .addDnsName("localhost")
                .addIpAddress(ipAddress)
                .addIpAddress("127.0.0.1")
                .setSignatureAlgorithm(SelfSignedCertificateBuilder.SA_SHA256_RSA)
                .build();
    }

    /**
     * 验证类型定义节点是否存在
     */
    private boolean validateTypeDefinitionNodes() {
        try {
            log.debug("开始验证类型定义节点...");
            // 检查FolderType节点是否存在
            if (!nodeContext.getNode(FOLDER_TYPE_ID).isPresent()) {
                log.error("未找到FolderType节点，无法创建文件夹节点");
                return false;
            }
            // 检查BaseDataVariableType节点是否存在
            if (!nodeContext.getNode(BASE_DATA_VARIABLE_TYPE_ID).isPresent()) {
                log.error("未找到BaseDataVariableType节点，无法创建变量节点");
                return false;
            }
            log.debug("类型定义节点验证通过");
            return true;
        } catch (Exception e) {
            log.error("验证类型定义节点时发生错误", e);
            return false;
        }
    }

    private void registerCustomNamespaceAndNodeManager() {
        try {
            NamespaceTable namespaceTable = server.getNamespaceTable();
            log.debug("开始注册自定义命名空间和节点管理器...");

            // 检查命名空间是否已存在
            UShort existingIndex = namespaceTable.getIndex(NAMESPACE_URI);
            if (existingIndex != null) {
                namespaceIndex = existingIndex;
                log.info("命名空间已存在: {} (索引: {})", NAMESPACE_URI, namespaceIndex.intValue());
            } else {
                // 注册新的命名空间
                namespaceIndex = namespaceTable.addUri(NAMESPACE_URI);
                log.info("注册自定义命名空间: {} (索引: {})", NAMESPACE_URI, namespaceIndex.intValue());
            }

            // 创建并注册节点管理器
            if (customNamespaceNodeManager == null) {
                customNamespaceNodeManager = createNodeManager();
                addressSpaceManager.register(customNamespaceNodeManager);
                log.info("已注册自定义节点管理器");
            }

            // 打印命名空间表
            printNamespaceTable(namespaceTable);
        } catch (Exception e) {
            log.error("注册命名空间和节点管理器失败", e);
        }
    }

    /**
     * 创建节点管理器（适配Milo 0.6.13）
     */
    private NodeManager<UaNode> createNodeManager() {
        log.debug("创建自定义节点管理器");
        return new NodeManager<UaNode>() {
            // 使用ConcurrentHashMap提高并发性能
            private final Map<NodeId, UaNode> nodes = new ConcurrentHashMap<>();
            private final Map<NodeId, List<Reference>> references = new ConcurrentHashMap<>();

            @Override
            public boolean containsNode(NodeId nodeId) {
                return nodes.containsKey(nodeId);
            }

            @Override
            public boolean containsNode(ExpandedNodeId nodeId, NamespaceTable namespaceTable) {
                try {
                    return nodeId.toNodeId(namespaceTable).map(this::containsNode).orElse(false);
                } catch (Exception e) {
                    return false;
                }
            }

            @Override
            public Optional<UaNode> addNode(UaNode node) {
                if (node == null) return Optional.empty();

                NodeId nodeId = node.getNodeId();
                // 使用putIfAbsent确保原子性
                UaNode existingNode = nodes.putIfAbsent(nodeId, node);
                if (existingNode == null) {
                    references.computeIfAbsent(nodeId, k -> new CopyOnWriteArrayList<>());
                    log.debug("节点已添加到管理器: {}", nodeId);
                    return Optional.of(node);
                }
                log.debug("节点已存在于管理器中: {}", nodeId);
                return Optional.empty();
            }

            @Override
            public Optional<UaNode> getNode(NodeId nodeId) {
                return Optional.ofNullable(nodes.get(nodeId));
            }

            @Override
            public Optional<UaNode> getNode(ExpandedNodeId nodeId, NamespaceTable namespaceTable) {
                return nodeId.toNodeId(namespaceTable).flatMap(this::getNode);
            }

            @Override
            public Optional<UaNode> removeNode(NodeId nodeId) {
                UaNode removedNode = nodes.remove(nodeId);
                if (removedNode != null) {
                    references.remove(nodeId);
                    // 移除所有指向该节点的引用
                    references.values().forEach(refList ->
                            refList.removeIf(ref -> ref.getTargetNodeId().equals(nodeId))
                    );
                    log.debug("节点已从管理器移除: {}", nodeId);
                    return Optional.of(removedNode);
                }
                log.debug("节点不存在于管理器中，无法移除: {}", nodeId);
                return Optional.empty();
            }

            @Override
            public Optional<UaNode> removeNode(ExpandedNodeId nodeId, NamespaceTable namespaceTable) {
                return nodeId.toNodeId(namespaceTable).flatMap(this::removeNode);
            }

            @Override
            public void addReference(Reference reference) {
                if (reference == null) return;

                NodeId sourceNodeId = reference.getSourceNodeId();
                if (containsNode(sourceNodeId)) {
                    references.computeIfAbsent(sourceNodeId, k -> new CopyOnWriteArrayList<>())
                            .add(reference);
                    log.trace("添加引用: {} -> {}", sourceNodeId, reference.getTargetNodeId());
                }
            }

            @Override
            public void addReferences(Reference reference, NamespaceTable namespaceTable) {
                NodeId sourceNodeId = reference.getSourceNodeId();
                ExpandedNodeId targetExpandedNodeId = reference.getTargetNodeId();
                NodeId targetNodeId;
                try {
                    targetNodeId = targetExpandedNodeId.toNodeId(namespaceTable)
                            .orElseThrow(() -> new IllegalArgumentException("Invalid target node id: " + targetExpandedNodeId));
                } catch (Exception e) {
                    log.error("解析目标节点ID失败", e);
                    return;
                }

                Reference convertedReference = new Reference(
                        sourceNodeId,
                        reference.getReferenceTypeId(),
                        targetNodeId.expanded(),
                        reference.isForward()
                );

                addReference(convertedReference);
            }

            @Override
            public void removeReference(Reference reference) {
                if (reference == null) return;

                NodeId sourceNodeId = reference.getSourceNodeId();
                references.getOrDefault(sourceNodeId, Collections.emptyList())
                        .removeIf(ref -> ref.equals(reference));
                log.trace("移除引用: {} -> {}", sourceNodeId, reference.getTargetNodeId());
            }

            @Override
            public void removeReferences(Reference reference, NamespaceTable namespaceTable) {
                NodeId sourceNodeId = reference.getSourceNodeId();
                ExpandedNodeId targetExpandedNodeId = reference.getTargetNodeId();
                NodeId targetNodeId;
                try {
                    targetNodeId = targetExpandedNodeId.toNodeId(namespaceTable)
                            .orElse(null);
                } catch (Exception e) {
                    log.error("解析目标节点ID失败", e);
                    return;
                }

                if (targetNodeId == null) return;

                Reference convertedReference = new Reference(
                        sourceNodeId,
                        reference.getReferenceTypeId(),
                        targetNodeId.expanded(),
                        reference.isForward()
                );

                removeReference(convertedReference);
            }

            @Override
            public List<Reference> getReferences(NodeId nodeId) {
                return new ArrayList<>(references.getOrDefault(nodeId, Collections.emptyList()));
            }

            @Override
            public List<Reference> getReferences(NodeId sourceNodeId, Predicate<Reference> filter) {
                // 兼容占位符：如果sourceNodeId是NULL_VALUE，则返回所有符合条件的引用
                if (sourceNodeId == null || NodeId.NULL_VALUE.equals(sourceNodeId)) {
                    List<Reference> allReferences = new ArrayList<>();
                    // 遍历所有引用并应用过滤条件
                    for (List<Reference> refs : references.values()) {
                        allReferences.addAll(refs.stream().filter(filter).collect(Collectors.toList()));
                    }
                    return allReferences;
                } else {
                    // 正常按sourceNodeId查询
                    List<Reference> refs = references.getOrDefault(sourceNodeId, Collections.emptyList());
                    return refs.stream().filter(filter).collect(Collectors.toList());
                }
            }
        };
    }

    private boolean validateNamespaceRegistration() {
        try {
            log.debug("验证命名空间注册...");
            if (namespaceIndex == null) {
                log.error("命名空间索引未初始化");
                return false;
            }

            NamespaceTable namespaceTable = server.getNamespaceTable();
            String registeredUri = namespaceTable.getUri(namespaceIndex);
            if (!NAMESPACE_URI.equals(registeredUri)) {
                log.error("命名空间验证失败 - 预期: {}, 实际: {}", NAMESPACE_URI, registeredUri);
                return false;
            }

            // 验证默认命名空间
            String defaultNamespace = namespaceTable.getUri(Unsigned.ushort(0));
            if (!OPC_UA_DEFAULT_NAMESPACE.equals(defaultNamespace)) {
                log.warn("默认命名空间不匹配 - 预期: {}, 实际: {}",
                        OPC_UA_DEFAULT_NAMESPACE, defaultNamespace);
            }
            log.debug("命名空间注册验证通过");
            return true;
        } catch (Exception e) {
            log.error("验证命名空间注册时发生错误", e);
            return false;
        }
    }

    private void printNamespaceTable(NamespaceTable namespaceTable) {
        try {
            log.info("已注册的命名空间:");
            String[] uris = namespaceTable.toArray();

            for (String s : uris) {
                UShort index = namespaceTable.getIndex(s);
                if (index != null) {
                    log.info("  索引 {}: {}", index.intValue(), s);
                }
            }
        } catch (Exception e) {
            log.error("打印命名空间表时发生错误", e);
        }
    }

    /**
     * 批量添加节点
     */
    public int addNodes(List<UaNode> nodes, UaNode parentNode) {
        if (nodes == null || nodes.isEmpty() || parentNode == null) {
            log.error("节点列表为空或父节点为空，无法执行批量添加");
            return 0;
        }

        log.info("开始批量添加节点，总数: {}, 父节点: {}", nodes.size(), parentNode.getNodeId());
        int successCount = 0;
        for (UaNode node : nodes) {
            if (addNode(node, parentNode)) {
                successCount++;
            }
        }
        log.info("批量添加节点完成，成功: {}，失败: {}", successCount, nodes.size() - successCount);
        return successCount;
    }

    /**
     * 添加单个节点
     */
    public boolean addNode(UaNode node, UaNode parentNode) {
        try {
            if (node == null || parentNode == null) {
                log.error("节点或父节点不能为空");
                return false;
            }

            if (customNamespaceNodeManager == null) {
                log.error("节点管理器未初始化，无法添加节点");
                return false;
            }

            NodeId nodeId = node.getNodeId();
            // 添加节点
            boolean nodeAdded = customNamespaceNodeManager.addNode(node).isPresent();
            if (!nodeAdded) {
                log.warn("节点添加失败，可能已存在: {}", nodeId);
                return false;
            }

            // 建立与父节点的引用关系
            addNodeHierarchyReferences(parentNode, node);
            log.info("节点添加成功: {}", nodeId);
            return true;
        } catch (Exception e) {
            log.error("添加节点失败: {}", node != null ? node.getNodeId() : "null", e);
            return false;
        }
    }

    /**
     * 批量删除节点
     */
    public int removeNodes(List<NodeId> nodeIds) {
        if (nodeIds == null || nodeIds.isEmpty()) {
            log.error("节点ID列表为空，无法执行批量删除");
            return 0;
        }

        log.info("开始批量删除节点，总数: {}", nodeIds.size());
        int successCount = 0;
        for (NodeId nodeId : nodeIds) {
            if (removeNode(nodeId)) {
                successCount++;
            }
        }
        log.info("批量删除节点完成，成功: {}，失败: {}", successCount, nodeIds.size() - successCount);
        return successCount;
    }

    /**
     * 删除单个节点
     */
    public boolean removeNode(NodeId nodeId) {
        try {
            if (nodeId == null) {
                log.error("节点ID不能为空");
                return false;
            }

            if (customNamespaceNodeManager == null) {
                log.error("节点管理器未初始化，无法删除节点");
                return false;
            }

            Optional<UaNode> removedNode = customNamespaceNodeManager.removeNode(nodeId);
            if (removedNode.isPresent()) {
                log.info("节点删除成功: {}", nodeId);
                return true;
            } else {
                log.warn("节点删除失败，节点不存在: {}", nodeId);
                return false;
            }
        } catch (Exception e) {
            log.error("删除节点失败: {}", nodeId, e);
            return false;
        }
    }

    /**
     * 批量更新变量节点值，如果节点不存在则自动创建
     */
    public int updateOrCreateVariableValues(Map<NodeId, Object> values) {
        return updateOrCreateVariableValues(values, DEFAULT_PARENT_NODE_ID);
    }

    /**
     * 批量更新变量节点值，如果节点不存在则自动创建
     */
    public int updateOrCreateVariableValues(Map<NodeId, Object> values, NodeId parentNodeId) {
        if (values == null || values.isEmpty()) {
            log.error("值映射为空，无法执行批量更新/创建");
            return 0;
        }

        if (parentNodeId == null) {
            log.warn("父节点ID为空，使用默认父节点: {}", DEFAULT_PARENT_NODE_ID);
            parentNodeId = DEFAULT_PARENT_NODE_ID;
        }

        UaNode parentNode = getNode(parentNodeId);
        if (parentNode == null) {
            log.error("父节点不存在: {}", parentNodeId);
            return 0;
        }

        log.info("开始批量更新/创建变量节点，总数: {}, 父节点: {}", values.size(), parentNodeId);
        int successCount = 0;
        int updateCount = 0;
        int createCount = 0;

        for (Map.Entry<NodeId, Object> entry : values.entrySet()) {
            NodeId nodeId = entry.getKey();
            Object value = entry.getValue();

            // 检查节点是否存在
            UaNode existingNode = getNode(nodeId);

            if (existingNode != null) {
                // 节点存在，更新值
                if (updateVariableValue(nodeId, value)) {
                    successCount++;
                    updateCount++;
                }
            } else {
                // 节点不存在，创建新节点
                if (createAndAddVariableNode(nodeId, value, parentNode)) {
                    successCount++;
                    createCount++;
                }
            }
        }

        log.info("批量更新/创建节点完成 - 总计: {} (更新: {}, 创建: {}), 失败: {}",
                successCount, updateCount, createCount, values.size() - successCount);
        return successCount;
    }

    /**
     * 创建并添加变量节点到指定父节点
     */
    private boolean createAndAddVariableNode(NodeId nodeId, Object value, UaNode parentNode) {
        try {
            // 验证类型定义节点
            Optional<UaNode> typeNode = nodeContext.getNode(BASE_DATA_VARIABLE_TYPE_ID);
            if (!typeNode.isPresent()) {
                log.error("BaseDataVariableType节点不存在，无法创建变量节点: {}", nodeId);
                return false;
            }

            // 确定数据类型
            NodeId dataTypeId = getDataTypeId(value);

            // 获取节点标识符
            Object identifier = nodeId.getIdentifier();
            String identifierStr = identifier.toString();

            // 创建变量节点构建器
            UaVariableNode.UaVariableNodeBuilder nodeBuilder = new UaVariableNode.UaVariableNodeBuilder(nodeContext)
                    .setNodeId(nodeId)
                    .setBrowseName(new QualifiedName(nodeId.getNamespaceIndex(), identifierStr))
                    .setDisplayName(LocalizedText.english(identifierStr))
                    .setDescription(LocalizedText.english("Auto-created variable node: " + identifierStr))
                    .setDataType(dataTypeId)
                    .setAccessLevel(UByte.valueOf(3)) // 可读可写
                    .setUserAccessLevel(UByte.valueOf(3))
                    .setMinimumSamplingInterval(500D)
                    .setHistorizing(false)
                    .setValue(new DataValue(
                            new Variant(value),
                            StatusCode.GOOD,
                            DateTime.now()
                    ))
                    .setWriteMask(UInteger.MAX)  // 确保可浏览
                    .setUserWriteMask(UInteger.MAX);

            // 构建节点
            UaVariableNode variableNode = nodeBuilder.build();

            // 添加类型定义引用
            variableNode.addReference(new Reference(
                    nodeId,
                    BuiltinReferenceType.HasTypeDefinition.getNodeId(),
                    BASE_DATA_VARIABLE_TYPE_ID.expanded(),
                    false
            ));

            // 添加节点到管理器
            boolean nodeAdded = customNamespaceNodeManager.addNode(variableNode).isPresent();
            if (!nodeAdded) {
                log.error("节点添加到自定义管理器失败: {}", nodeId);
                return false;
            }

            // 建立引用关系
            addNodeHierarchyReferences(parentNode, variableNode);

            log.debug("节点创建并注册成功: {}", nodeId);
            return true;
        } catch (Exception e) {
            log.error("创建变量节点失败: {}", nodeId, e);
            return false;
        }
    }

    /**
     * 根据值的类型获取对应的OPC UA数据类型ID
     */
    private NodeId getDataTypeId(Object value) {
        if (value == null) {
            return Identifiers.BaseDataType;
        }

        Class<?> clazz = value.getClass();

        if (clazz == Integer.class || clazz == int.class) {
            return Identifiers.Int32;
        } else if (clazz == Long.class || clazz == long.class) {
            return Identifiers.Int64;
        } else if (clazz == Float.class || clazz == float.class) {
            return Identifiers.Float;
        } else if (clazz == Double.class || clazz == double.class) {
            return Identifiers.Double;
        } else if (clazz == Boolean.class || clazz == boolean.class) {
            return Identifiers.Boolean;
        } else if (clazz == String.class) {
            return Identifiers.String;
        } else if (clazz == DateTime.class) {
            return Identifiers.DateTime;
        } else if (clazz == ByteString.class) {
            return Identifiers.ByteString;
        } else {
            // 默认使用字符串类型
            log.warn("不支持的数据类型: {}, 将使用String类型", clazz.getName());
            return Identifiers.String;
        }
    }

    /**
     * 更新单个变量节点值
     */
    public boolean updateVariableValue(NodeId nodeId, Object value) {
        try {
            UaNode node = getNode(nodeId);
            if (node == null) {
                log.error("节点不存在: {}", nodeId);
                return false;
            }

            if (!(node instanceof UaVariableNode)) {
                log.error("节点不是变量节点: {}", nodeId);
                return false;
            }

            UaVariableNode variableNode = (UaVariableNode) node;
            variableNode.setValue(new DataValue(
                    new Variant(value),
                    StatusCode.GOOD,
                    DateTime.now()
            ));

            server.getEventBus().post(new ValueChangedEvent(variableNode));
            log.debug("节点值更新成功: {}, 新值: {}", nodeId, value);
            return true;
        } catch (Exception e) {
            log.error("更新节点值失败: {}", nodeId, e);
            return false;
        }
    }

    /**
     * 批量获取变量节点值
     */
    public Map<NodeId, Object> getVariableValues(List<NodeId> nodeIds) {
        Map<NodeId, Object> result = new HashMap<>();
        if (nodeIds == null || nodeIds.isEmpty()) {
            log.error("节点ID列表为空，无法执行批量获取");
            return result;
        }

        log.info("开始批量获取变量节点值，总数: {}", nodeIds.size());
        int successCount = 0;

        for (NodeId nodeId : nodeIds) {
            Object value = getVariableValue(nodeId);
            if (value != null) {
                result.put(nodeId, value);
                successCount++;
            }
        }

        log.info("批量获取节点值完成，成功: {}，失败: {}", successCount, nodeIds.size() - successCount);
        return result;
    }

    /**
     * 获取单个变量节点值
     */
    public Object getVariableValue(NodeId nodeId) {
        try {
            UaNode node = getNode(nodeId);
            if (node == null) {
                log.error("节点不存在: {}", nodeId);
                return null;
            }

            if (!(node instanceof UaVariableNode)) {
                log.error("节点不是变量节点: {}", nodeId);
                return null;
            }

            UaVariableNode variableNode = (UaVariableNode) node;
            Variant variant = variableNode.getValue().getValue();
            Object value = variant.getValue();
            log.debug("获取节点值成功: {}, 值: {}", nodeId, value);
            return value;
        } catch (Exception e) {
            log.error("获取节点值失败: {}", nodeId, e);
            return null;
        }
    }

    /**
     * 获取父节点的所有子节点
     */
    public List<UaNode> getChildNodes(NodeId parentNodeId) {
        Set<UaNode> childrenSet = new HashSet<>();
        if (parentNodeId == null) return new ArrayList<>(childrenSet);

        try {
            // 1. 从所有管理器获取引用（包含内置和自定义）
            List<Reference> allReferences = addressSpaceManager.getManagedReferences(
                    parentNodeId,
                    ref -> ref.isForward() &&
                            (ref.getReferenceTypeId().equals(BuiltinReferenceType.Organizes.getNodeId()) ||
                                    ref.getReferenceTypeId().equals(BuiltinReferenceType.HasComponent.getNodeId()))
            );

            // 2. 解析并验证所有引用
            for (Reference ref : allReferences) {
                NodeId childNodeId;
                try {
                    childNodeId = ref.getTargetNodeId().toNodeId(server.getNamespaceTable()).orElse(null);
                } catch (Exception e) {
                    log.error("解析子节点ID失败", e);
                    continue;
                }

                if (childNodeId != null) {
                    // 从地址空间管理器获取节点（确保是托管节点）
                    Optional<UaNode> childNode = addressSpaceManager.getManagedNode(childNodeId);
                    if (childNode.isPresent()) {
                        childrenSet.add(childNode.get());
                        log.trace("有效子节点: {} (引用类型: {})",
                                childNodeId,
                                getReferenceTypeName(ref.getReferenceTypeId()));
                    }
                }
            }

            log.info("父节点{}下的有效子节点数量: {}", parentNodeId, childrenSet.size());
        } catch (Exception e) {
            log.error("获取子节点失败", e);
        }

        return new ArrayList<>(childrenSet);
    }

    /**
     * 辅助方法：获取引用类型名称
     */
    private String getReferenceTypeName(NodeId refTypeId) {
        Optional<UaNode> refNode = addressSpaceManager.getManagedNode(refTypeId);
        if (refNode.isPresent()) {
            return refNode.get().getBrowseName().getName();
        }
        return "Unknown";
    }

    /**
     * 获取指定ID的节点
     */
    private UaNode getNode(NodeId nodeId) {
        try {
            // 1. 优先从节点上下文查找（适用于所有节点）
            Optional<UaNode> contextNode = nodeContext.getNode(nodeId);
            if (contextNode.isPresent()) {
                log.trace("从节点上下文获取节点成功: {}", nodeId);
                return contextNode.get();
            }

            // 2. 按命名空间查询对应管理器
            if (nodeId.getNamespaceIndex().intValue() == 0) {
                // 内置节点从地址空间管理器查找
                Optional<UaNode> managedNode = server.getAddressSpaceManager().getManagedNode(nodeId);
                if (managedNode.isPresent()) {
                    return managedNode.get();
                }
            } else {
                // 自定义节点从自定义管理器查找
                if (customNamespaceNodeManager != null) {
                    Optional<UaNode> customNode = customNamespaceNodeManager.getNode(nodeId);
                    if (customNode.isPresent()) {
                        return customNode.get();
                    }
                }
            }

            log.warn("节点 {} 未在任何管理器或上下文中找到", nodeId);
            return null;
        } catch (Exception e) {
            log.error("获取节点 {} 失败", nodeId, e);
            return null;
        }
    }

    /**
     * 启动值更新器，定期更新示例节点的值
     */
    private void startValueUpdater() {
        try {
            UaVariableNode demoNode = demoNodeRef.get();
            if (demoNode == null) {
                log.error("示例节点为空，无法启动更新器");
                return;
            }

            ScheduledExecutorService scheduledExecutor = server.getScheduledExecutorService();

            scheduledExecutor.scheduleAtFixedRate(() -> {
                try {
                    // 更新示例节点值（0-100之间随机变化）
                    double currentValue = (Double) demoNode.getValue().getValue().getValue();
                    double newValue = currentValue + (random.nextDouble() - 0.5) * 2;
                    newValue = Math.max(0.0, Math.min(100.0, newValue));

                    demoNode.setValue(new DataValue(new Variant(newValue)));
                    server.getEventBus().post(new ValueChangedEvent(demoNode));

                    // 定期打印日志
                    if (newValue % 5 < 0.5) {
                        log.info(String.format("示例节点值更新: %.2f", newValue));
                    }
                } catch (Exception e) {
                    log.error("更新示例节点值失败", e);
                    try {
                        if (namespaceIndex != null && customNamespaceNodeManager != null) {
                            NodeId demoNodeId = new NodeId(namespaceIndex, "DemoVariable");
                            demoNodeRef.set((UaVariableNode) customNamespaceNodeManager.getNode(demoNodeId).orElse(null));

                            if (demoNodeRef.get() == null) {
                                log.error("无法从节点管理器获取示例节点，停止更新器");
                                stop();
                            }
                        } else {
                            log.error("命名空间索引或节点管理器为空，无法重新获取节点，停止更新器");
                            stop();
                        }
                    } catch (Exception ex) {
                        log.error("重新获取节点失败，停止更新器", ex);
                        stop();
                    }
                }
            }, 0, UPDATE_INTERVAL_SECONDS, TimeUnit.SECONDS);

            log.info("值更新器已启动，更新间隔: {}秒", UPDATE_INTERVAL_SECONDS);
        } catch (Exception e) {
            log.error("启动值更新器失败", e);
        }
    }

    /**
     * 停止服务器
     */
    public void stop() {
        if (!isRunning.get()) {
            log.info("OPC UA服务器已停止");
            return;
        }

        log.info("停止OPC UA服务器...");
        isRunning.set(false);

        try {
            // 注销节点管理器
            if (customNamespaceNodeManager != null) {
                addressSpaceManager.unregister(customNamespaceNodeManager);
                log.debug("节点管理器已注销");
            }

            // 关闭执行器
            if (executor != null && !executor.isShutdown()) {
                executor.shutdown();
                if (!executor.awaitTermination(EXECUTOR_TERMINATION_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
                    List<Runnable> remainingTasks = executor.shutdownNow();
                    log.warn("执行器强制关闭，剩余任务数: {}", remainingTasks.size());
                }
                log.debug("执行器已关闭");
            }

            // 关闭服务器
            if (server != null) {
                CompletableFuture<OpcUaServer> future = server.shutdown();
                future.get(SERVER_SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS);
                log.debug("服务器已关闭");
            }

            log.info("OPC UA服务器已成功停止");
        } catch (Exception e) {
            log.error("服务器关闭过程中发生错误", e);
        }
    }

    /**
     * 静态方法：停止服务器
     */
    public static void stopServer() {
        if (instance != null) {
            instance.stop();
            instance = null;
        } else {
            log.info("OPC UA服务器未运行，无需停止");
        }
    }

    /**
     * 值变更事件类
     */
    @Getter
    private static class ValueChangedEvent {
        private final UaNode node;

        public ValueChangedEvent(UaNode node) {
            this.node = node;
        }
    }

    /**
     * 节点添加事件类
     */
    @Getter
    private static class NodeAddedEvent {
        private final UaNode node;

        public NodeAddedEvent(UaNode node) {
            this.node = node;
        }
    }

    public String getNamespaceUri() {
        return NAMESPACE_URI;
    }

    public NamespaceTable getNamespaceTable() {
        try {
            return server.getNamespaceTable();
        } catch (Exception e) {
            log.error("获取命名空间表失败", e);
            return new NamespaceTable();
        }
    }

    public boolean isRunning() {
        return isRunning.get();
    }

    /**
     * 获取Server节点作为父节点
     */
    public UaNode getServerNodeAsParent() {
        return getNode(SERVER_NODE_ID);
    }

    /**
     * 使用示例
     */
    public static void main(String[] args) {
        try {
            // 1. 启动服务器
            OpcUaServer1Util server = OpcUaServer1Util.startServer("0.0.0.0", 12685);
            UShort namespaceIndex = server.getNamespaceTable().getIndex(server.getNamespaceUri());

            if (namespaceIndex != null) {
                // 2. 批量更新/创建节点
                Map<NodeId, Object> values = new HashMap<>();
                values.put(new NodeId(namespaceIndex, "Temperature"), 25.6);
                values.put(new NodeId(namespaceIndex, "Pressure"), 101.3);
                values.put(new NodeId(namespaceIndex, "Humidity"), 45.2);
                values.put(new NodeId(namespaceIndex, "Status"), "Running");

                // 使用Objects节点作为父节点
                int updatedCount = server.updateOrCreateVariableValues(values, Identifiers.ObjectsFolder);
                log.info("批量更新/创建了 {} 个节点", updatedCount);

                // 验证子节点
                List<UaNode> children = server.getChildNodes(Identifiers.ObjectsFolder);
                log.info("Objects节点下的子节点数量: {}", children.size());
                for (UaNode node : children) {
                    log.info("子节点: {} ({})", node.getBrowseName(), node.getNodeId());
                }

                // 运行一段时间
                log.info("服务器将运行5分钟...");
                Thread.sleep(5 * 60000);

                // 停止服务器
                log.info("准备停止服务器...");
                OpcUaServer1Util.stopServer();
            }
        } catch (Exception e) {
            log.error("服务器运行出错", e);
            OpcUaServer1Util.stopServer();
        }
    }
}
